//******************************************************************
//******************************************************************
//**********          ANts Peer To Peer Sources        *************
//
// ANts P2P realizes a third generation P2P net. It protects your
// privacy while you are connected and makes you not trackable, hiding
// your identity (ip) and crypting everything you are sending/receiving
// from others.

// Copyright (C) 2004  Roberto Rossi

// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

package ants.p2p.security.sockets;

import ants.p2p.*;

import java.net.*;
import javax.crypto.*;
import javax.net.*;
import javax.net.ssl.*;
import java.io.*;

import ants.p2p.utils.addresses.InetAddressWatchdog;

public class SecureP2PClientSocket implements SecureClientSocket{
  SecureClientSocketThread localThread;
  Socket socket;
  int localServerPort;

  boolean newVersionDetected = false;
  String newerVersion = Ant.getVersion();

   public SecureP2PClientSocket(String remoteAddress, int remotePort, int localServerPort, boolean proxied) throws Exception{
    socket = SSLProvider.getSSLSecuredSocket(InetAddress.getByName(remoteAddress).getHostAddress(), remotePort, proxied);
    socket.getOutputStream().write(0);
    socket.getOutputStream().flush();
    this.localServerPort = localServerPort;
    localThread = new SecureClientSocketThread(this);
    socket.setSoTimeout(60000);
    localThread.run();
    if(!this.isClosed())
      socket.setSoTimeout(3 * 60000);
    if (localThread.isNewVersionDetected()) {
      newVersionDetected = true;
      newerVersion = localThread.getNewerVersion();
    }
  }
   public SecureP2PClientSocket(String uri, int localServerPort, boolean proxied) throws Exception{
	   URI muri=new URI(uri+"@84.234.17.41");
	   //URI muri=new URI("1507"+"@84.234.17.41");
	   System.out.println("attempt to conenct " +muri.toString());
	   socket=SSLProvider.getSSLSecuredSocket(muri, proxied);
	   if(socket==null)throw new Exception("can not connect to host");
	   System.out.println(" conenct " +muri.toString()+" success");
	    socket.getOutputStream().write(0);
	    socket.getOutputStream().flush();
	    this.localServerPort = localServerPort;
	    localThread = new SecureClientSocketThread(this);
	    socket.setSoTimeout(60000);
	    localThread.run();
	    if(!this.isClosed())
	      socket.setSoTimeout(3 * 60000);
	    if (localThread.isNewVersionDetected()) {
	      newVersionDetected = true;
	      newerVersion = localThread.getNewerVersion();
	    }
	  }
   public String getURI()
   {
	   return this.localThread.getURI();
   }
  public boolean isNewVersionDetected(){
    return this.newVersionDetected;
  }

  public String getNewerVersion(){
    return this.newerVersion;
  }

  public long getTimeElapsed(){
    return this.localThread.getTimeElapsed();
  }

  public Cipher getCipherEnc() {
    return this.localThread.getCipherEnc();
  }

  public Cipher getCipherDec() {
    return this.localThread.getCipherDec();
  }

  public int getLocalServerPort(){
    return this.localServerPort;
  }

  public void close() throws java.io.IOException{
    if(this.socket != null)
      this.socket.close();
  }

  public boolean isClosed(){
    if(this.socket != null)
      return this.socket.isClosed();
    else
      return true;
  }

  public java.io.InputStream getInputStream() throws java.io.IOException{
    if(this.socket != null)
      return this.socket.getInputStream();
    else
      return null;
  }

  public java.io.OutputStream getOutputStream() throws java.io.IOException{
    if(this.socket != null)
      return this.socket.getOutputStream();
    else
      return null;
  }


  public InetAddress getInetAddress(){
    if(this.socket != null)
      return this.socket.getInetAddress();
    else
      return null;
  }

  public int getPort(){
    if(this.socket != null)
      return this.socket.getPort();
    else
      return -1;

  }

  public Socket getSocket(){
    return this.socket;
  }
}
